<?php
declare(strict_types=1);

namespace app\api\listener;

use app\api\model\PaymentLog;
use app\api\model\User;
use app\api\model\User as UserModel;
use app\api\model\user\BalanceLog as BalanceLogModel;
use app\common\enum\AgentType;
use app\common\enum\coupon\CouponType;
use app\common\enum\order\PayType;
use app\common\enum\OrderType;
use app\common\enum\PointsType;
use app\common\enum\user\balanceLog\Scene as SceneEnum;
use app\common\model\Order;
use app\common\model\UserCoupon;
use think\Exception;
use think\facade\Db;
use think\facade\Event;
use think\facade\Log;

class PaymentHandle
{

    /**
     * @param array $data
     * @return bool
     * @throws Exception
     */
    public function handle(array $data): bool
    {
        Log::channel('wxpay')->info('支付成功开始处理余额：'.($data['trans_id'] ?? ''));
        $payment                   = $data['payment'];
        $payType                   = $data['payType'];
        $trans_id                  = $data['trans_id'] ?? '';
        $handle                    = $payment['handle'];
        $class                     = 'app\\api\\service\\pay\\' . $handle;
        $handleClass               = new $class();
        $payment['transaction_id'] = $trans_id;
        Db::startTrans();
        try {
            if ($payType == PayType::BALANCE) {
                // 余额
                $user = User::where('user_id', $payment['user_id'])->field('user_id,store_id,balance')->lock()->find();
                if ($user['balance'] < $payment['pay_price']) {
                    throw new \Exception("余额不足");
                }
                // 更新余额
                UserModel::setDecBalance((int)$payment['user_id'], (float)$payment['pay_price']);
                // 新增余额变动记录
                BalanceLogModel::add(SceneEnum::CONSUME, [
                    'user_id' => (int)$payment['user_id'],
                    'money'   => $payment['pay_price'] * -1,
                ], ['order_no' => $payment['order_no']]);
            }
            // 累积用户总消费金额
            $order_info = Order::where('order_no',$payment['order_no'])->find();
            $pre_card_money = 0;
            if($order_info['coupon_id'] > 0){
                $coupon_type = (new UserCoupon)->where('coupon_id',$order_info['coupon_id'])->value('coupon_type');
                if($coupon_type == CouponType::PRE_STORAGE_CARD){
                    $pre_card_money = $order_info['coupon_money'];
                }
            }
            //预存卡也属于消费金额
            $total_price = $payment['pay_price'] + $pre_card_money;
            //UserModel::setIncPayMoney($payment['user_id'], (float)$payment['pay_price']);
            UserModel::setIncPayMoney($payment['user_id'], (float)$total_price);
            // 更新付款记录
            PaymentLog::update([
                'pay_type'       => $payType,
                'pay_status'     => PaymentLog::PAY_SUCCESS,
                'pay_time'       => time(),
                'transaction_id' => $trans_id
            ], ['order_no' => $payment['order_no']]);
            //更新积分
            Log::channel('wxpay')->info('更新积分：'.$payment['order_no']);

            //$points_num = \app\common\model\Order::where('order_no',$payment['order_no'])->value('points_num');
            if($order_info->points_num > 0){
                UserModel::setDecPoints($payment['user_id'], $order_info->points_num, PointsType::data()[PointsType::DEDUCT]['name'], PointsType::DEDUCT, $payment['order_no']);
            }
            $handleClass->onSuccess($payment, $payType);
            //todo 分成订单处理
            Event::trigger('AgentOrderHandle', ['divide_info' => $order_info->toArray()]);
            Db::commit();
            $handleClass->callSuccess();
            return true;
        } catch (\Exception $exception) {
            Db::rollback();
            throw new Exception($exception->getMessage());
        }
    }
}